<?php

class Tree {
	private $config = array(
		'indent' 		=> '　　',		//缩进符号
		'parent_id' 	=> 'parent',	//记录父级ID的字段名称
		'children_name' => 'children',	//返回的树中，存放树支的节点名称
		'name_column'	=> 'name',		//名称列的名称 
		'id_column'		=> '_id',		//键列名
	);
	
	private $tree_data;
	
	public function Tree($data_list, $config=null){
		if($config!=null){
			$this->config = array_merge($this->config, $config);
		}
		$this->tree_data = array();
		$parent = $this->config['parent_id'];
		$children = $this->config['children_name'];
		$id_column = $this->config['id_column'];
		foreach ($data_list as $pid => &$item_data){
			if(!isset($item_data[$id_column]))$item_data[$id_column] = $pid; //补全_id
			if(isset($item_data[$parent]) && !empty($item_data[$parent])){
				$data_list[$item_data[$parent]][$children][$pid] = &$item_data;
			}
		}
		foreach ($data_list as $pid=>&$item_data){
			if(!isset($item_data[$parent]) || empty($item_data[$parent])){
				$this->tree_data[$pid] = $item_data;
			}
		}
	}
	
	public function get_tree(){
		return $this->tree_data;
	}
	
	public function get_formated_list($indent=null){
		if($indent==null)$indent = $this->config['indent'];
		
		return self::format_tree($this->tree_data, $indent);
	}
	
	public function get_options($indent=null, $default_text=null, $default_val=null){
		if($indent==null)$indent = $this->config['indent'];
		$temp_list = self::get_formated_list($indent);
		$ps = array();
		if($default_text!==null && $default_val!==null){
			$ps[(string)$default_val] = $default_text;
		}
		foreach ($temp_list as $pid=>$post){
			$ps[$pid] = $post['name'];
		}
		return $ps;
	}
	
	/**
	 * 
	 * @param unknown_type $post_list
	 * @param unknown_type $indent
	 */
	private function format_tree($data_list, $inc_indent, $parent_indent = ''){
		if(empty($data_list)) return null;
		$ps = array();
		$parent = $this->config['parent_id'];
		$children = $this->config['children_name'];
		$name_column = $this->config['name_column'];
		foreach ($data_list as $pid=>$item){
			$item[$name_column] = $parent_indent . $item[$name_column];
			$ps[$pid] = $item;
			if(isset($item[$children])){
				$ps = array_merge($ps, self::format_tree($item[$children], $inc_indent, $parent_indent . $inc_indent));
				unset($ps[$pid][$children]);
			}
		}
		return $ps;
	}
	
	/**
	 * 获取某一节点及其子节点的ID数组
	 * @param unknown_type $node_id
	 */
	public function get_children_ids($node_id){
		$nodes = self::get_children($node_id);
		return self::get_node_ids($nodes);
	}
	
	private function get_node_ids($tree_data){
		$ids = array($tree_data[$this->config['id_column']]);
		if(isset($tree_data[$this->config['children_name']])){
			foreach($tree_data[$this->config['children_name']] as $id=>$node){
				$children_ids = self::get_node_ids($node);
				$ids = array_merge($ids, $children_ids);
			}
		}
		return $ids;
	}
	
	public function get_children($node_id){
		return self::get_tree_node($this->tree_data, $node_id);
	}
	
	private function get_tree_node($tree_data, $node_id){
		foreach($tree_data as $id=>$node){
			if($id == $node_id){
				return $node;
			}
			if(isset($node[$this->config['children_name']])){
				$result = self::get_tree_node($node[$this->config['children_name']], $node_id);
				if($result != null){
					return $result;
				}
			}
		}
		return null;
	}
	
}

?>